/**
 * Copyright 2011 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.google.solarchallenge.client.gwtui.widgets.solarchallengeheaderbar;

import static com.google.solarchallenge.client.rpc.ServiceProvider.getServiceProvider;
import static com.google.solarchallenge.shared.Utils.RedirectionUtils.generateValidParamsToAttach;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Frame;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.MenuItem;
import com.google.gwt.user.client.ui.PopupPanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import com.google.solarchallenge.client.event.EventCategory;
import com.google.solarchallenge.client.event.HistoryHandler;
import com.google.solarchallenge.client.gwtui.mvpinterfaces.View;
import com.google.solarchallenge.shared.ServletPaths;
import com.google.solarchallenge.shared.ValidParams;
import com.google.solarchallenge.shared.dtos.UserAccountDto;

/**
 * View for HeaderBar.
 *
 * @author Arjun Satyapal
 */
public class SolarChallengeHeaderBarView extends View implements
    SolarChallengeHeaderBarDisplay {
  private boolean userLoggedIn = false;

  private void setUserLoggedIn(boolean isUserLoggedIn) {
    this.userLoggedIn = isUserLoggedIn;
  }

  private boolean getUserLoggedIn() {
    return userLoggedIn;
  }

  // Menu Items for Applicants..
  @UiField
  MenuItem menuApplicant;
  @UiField
  MenuItem menuItemApplicantRegister;
  @UiField
  MenuItem menuItemApplicantHome;
  @UiField
  MenuItem menuItemLoginLogout;

  // Menu Items for Approvers.
  @UiField
  MenuItem menuApprover;
  @UiField
  MenuItem menuItemApproverHome;

  // Menu Items for Admin.
  @UiField
  MenuItem menuAdmin;
  @UiField
  MenuItem menuItemAdminHome;

  private static SolarChallengeHeaderPanelViewUiBinder uiBinder = GWT
      .create(SolarChallengeHeaderPanelViewUiBinder.class);

  interface SolarChallengeHeaderPanelViewUiBinder extends
      UiBinder<Widget, SolarChallengeHeaderBarView> {
  }

  public SolarChallengeHeaderBarView() {
    initWidget(uiBinder.createAndBindUi(this));
  }

  @Override
  public void bind() {
    // TODO : Provide a logout url.
    updateMenuBar();

    // Handlers for MenuItems in Applicant Menu.
    menuItemApplicantRegister.setCommand(new Command() {
      @Override
      public void execute() {
        HistoryHandler.handleNewToken(
            EventCategory.APPLICANT_REGISTER.getToken());
      }
    });

    menuItemLoginLogout.setCommand(new Command() {
      @Override
      public void execute() {
        if (getUserLoggedIn() == false) {
          String token =
              HistoryHandler.createTokenWithParams(
                  EventCategory.LOGIN_UI,
                  generateValidParamsToAttach(
                      ValidParams.CLIENT_CALLBACK_TOKEN,
                      EventCategory.HOME.getToken()));
          HistoryHandler.handleNewToken(token);
        } else {
          handleLogout();
        }
      }

      private void handleLogout() {
        final PopupPanel popupPanel = new PopupPanel();
        popupPanel.setAnimationEnabled(true);
        popupPanel.setGlassEnabled(true);
        popupPanel.center();

        VerticalPanel vPanel = new VerticalPanel();
        Frame iFrame = new Frame(ServletPaths.LOGOUT.getRelativePath());
        iFrame.setSize("1px", "1px");
        Button buttonClose = new Button("Close");
        buttonClose.addClickHandler(new ClickHandler() {
          @Override
          public void onClick(ClickEvent event) {
            HistoryHandler.handleNewToken(EventCategory.HOME.getToken());
            popupPanel.hide();
          }
        });
        vPanel.add(iFrame);
        vPanel.add(new Label("Successfully Logged Out."));
        vPanel.add(buttonClose);
        popupPanel.add(vPanel);
        popupPanel.show();
      }
    });

    menuItemApplicantHome.setCommand(new Command() {
      @Override
      public void execute() {
        HistoryHandler.handleNewToken(EventCategory.APPLICANT_HOME.getToken());
      }
    });

    menuItemApproverHome.setCommand(new Command() {

      @Override
      public void execute() {
        Window.alert("Not yet implemented.");
      }
    });

    // Handlers for MenuItems in Admin Menu..
    menuItemAdminHome.setCommand(new Command() {
      @Override
      public void execute() {
        HistoryHandler.handleNewToken(EventCategory.ADMIN_UI.getToken());
      }
    });
  }

  @Override
  public SolarChallengeHeaderBarDisplay getSolarChallengeHeaderPanel() {
    return this;
  }

  @Override
  public MenuItem getMenuItemApplicantRegister() {
    return menuItemApplicantRegister;
  }

  @Override
  public void setEnabled(boolean enabled) {
    menuApplicant.setEnabled(enabled);
    menuApprover.setEnabled(enabled);
    menuAdmin.setEnabled(enabled);
    menuItemLoginLogout.setEnabled(enabled);
  }

  @Override
  public MenuItem getMenuItemLogOut() {
    return menuItemLoginLogout;
  }

  private void updateMenuBar() {
    AsyncCallback<UserAccountDto> callback = new AsyncCallback<UserAccountDto>() {
      @Override
      public void onFailure(Throwable caught) {
        Window.alert("Failed to get LoginStatus.");
      }

      @Override
      public void onSuccess(UserAccountDto userAccountDto) {
        // Successfully got the result for UserAccountDto.
        if (userAccountDto == null) {
          // User is not logged in.
          updateLogOutMenuItem(false /* isUserLoggedIn. */);
        } else {
          // User is logged in.
          updateLogOutMenuItem(true /* isUserLoggedIn. */);
        }
      }

      private void updateLogOutMenuItem(boolean isUserLoggedIn) {
        setUserLoggedIn(isUserLoggedIn);
        menuItemApplicantRegister.setVisible(!isUserLoggedIn);
        if (isUserLoggedIn) {
          menuItemLoginLogout.setText("Logout");
        } else {
          menuItemLoginLogout.setText("Login");
        }
      }
    };
    getServiceProvider().getLoginService().getLoggedInUserDTO(callback);
  }
}
